#ifndef __STATE_MACHINE_HPP__
#define __STATE_MACHINE_HPP__

#include <boost/mpl/list.hpp>

#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include "event.hpp"

namespace fsm
{
	namespace sc = boost::statechart;

	class StMain;
	class PcikBot : public sc::state_machine<PcikBot, StMain> {};

	class StIdle;
	class StWork;
	class StMain : public sc::simple_state<StMain, PcikBot, StIdle>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>,
			sc::transition<EvStart, StWork>,
			sc::transition<EvStop, StIdle>
		> reactions;

	public:
		StMain()
		{}

		~StMain()
		{}

	public:
		sc::result react(const EvTick&);
	};

	class StIdle : public sc::simple_state<StIdle, StMain>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>,
			sc::transition<EvStart, StWork>
		> reactions;

	public:
		StIdle()
		{}

		~StIdle()
		{}

	public:
		sc::result react(const EvTick&);
	};

	class StSearch;
	class StAttack;
	class StMove;
	class StWork : public sc::simple_state<StWork, StMain, StSearch>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>,
			sc::custom_reaction<EvSearchEnd>,
			sc::custom_reaction<EvMoveEnd>,
			sc::transition<EvAttackEnd, StSearch>
		> reactions;

	public:
		StWork()
		{}

		~StWork()
		{}

	public:
		sc::result react(const EvTick&);
		sc::result react(const EvSearchEnd& ev);
		sc::result react(const EvMoveEnd& ev);

	private:
		int monstrer_id_;
		int x_;
		int y_;
	};

	class StSearch : public sc::simple_state<StSearch, StWork>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>
		> reactions;

	public:
		StSearch()
		{}

		~StSearch()
		{}

	public:
		sc::result react(const EvTick&);
	};

	class StMove : public sc::simple_state<StMove, StWork>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>,
			sc::custom_reaction<EvMoveTo>
		> reactions;

	public:
		StMove()
		{}

		~StMove()
		{}

	public:
		sc::result react(const EvTick&);
		sc::result react(const EvMoveTo& ev_moveto);

	private:
		int x_;
		int y_;
	};


	class StAttack : public sc::simple_state<StAttack, StWork>
	{
	public:
		typedef boost::mpl::list<
			sc::custom_reaction<EvTick>,
			sc::custom_reaction<EvAttack>
		> reactions;

	public:
		StAttack()
		{}

		~StAttack()
		{}

	public:
		sc::result react(const EvTick&);
		sc::result react(const EvAttack& ev_kill);

	private:
		int monster_id_;
	};

}//namespace fsm

#endif//__STATE_MACHINE_HPP__